package com.llc.mall.common.database.qo;

import com.github.pagehelper.IPage;
import com.llc.mall.common.core.util.PrincipalUtil;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotNull;

public record BasePageQo(
        @NotNull(message = "pageNum 不能为空")
        @Schema(description = "当前页", requiredMode = Schema.RequiredMode.REQUIRED)
        Integer pageNum,
        @NotNull(message = "pageSize 不能为空")
        @Schema(description = "每页大小", requiredMode = Schema.RequiredMode.REQUIRED)
        Integer pageSize,
        @Schema(description = "排序字段数组，用逗号分割")
        String[] columns,
        @Schema(description = "排序字段方式，用逗号分割，ASC正序，DESC倒序")
        String[] orders
) implements IPage {

    public static final String ASC = "ASC";
    public static final String DESC = "DESC";
    /**
     * 最大分页大小，如果分页大小大于500，则用500作为分页的大小。防止有人直接传入一个较大的数，导致服务器内存溢出宕机
     */
    public static final Integer MAX_PAGE_SIZE = 500;

    @Override
    public Integer getPageNum() {
        return this.pageNum;
    }

    @Override
    public Integer getPageSize() {
        return this.pageSize > MAX_PAGE_SIZE ? MAX_PAGE_SIZE : this.pageSize;
    }

    @Override
    public String getOrderBy() {
        return order(this.columns, this.orders);
    }

    public static String order(String[] columns, String[] orders) {
        if (columns == null || columns.length == 0) {
            return "";
        }

        StringBuilder stringBuilder = new StringBuilder();

        for (int x = 0; x < columns.length; x++) {
            String column = columns[x];
            String order;

            if (orders != null && orders.length > x) {
                order = orders[x].toUpperCase();
                if (!(order.equals(ASC) || order.equals(DESC))) {
                    throw new IllegalArgumentException("非法的排序策略：" + column);
                }
            } else {
                order = ASC;
            }

            // 判断列名称的合法性，防止SQL注入。只能是【字母，数字，下划线】
            if (PrincipalUtil.isField(column)) {
                throw new IllegalArgumentException("非法的排序字段名称：" + column);
            }
            // 驼峰转换为下划线
            column = humpConversionUnderscore(column);
            if (x != 0) {
                stringBuilder.append(", ");
            }
            stringBuilder.append("`").append(column).append("` ").append(order);
        }
        return stringBuilder.toString();
    }

    public static String humpConversionUnderscore(String value) {
        StringBuilder stringBuilder = new StringBuilder();
        for (char character : value.toCharArray()) {
            if (Character.isUpperCase(character)) {
                stringBuilder.append("_");
                character = Character.toLowerCase(character);
            }
            stringBuilder.append(character);
        }
        return stringBuilder.toString();
    }

}
